package com.wennn.top.security.filter;

import com.wennn.top.security.exception.TokenException;
import com.wennn.top.security.model.JwtAuthToken;
import com.wennn.top.security.util.JwtUtil;
import com.wennn.top.security.util.SecurityConst;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.util.AntPathMatcher;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


/**
 * @description: 自定义JWT认证过滤器
 * 该类继承自BasicAuthenticationFilter，在doFilterInternal方法中，
 * 从http头的Authorization 项读取token数据，然后用Jwts包提供的方法校验token的合法性。
 * 如果校验通过，就认为这是一个取得授权的合法请求
 * @author: wennn
 * @date: 5/9/20 3:55 PM
 */
@Slf4j
public class JWTBasicAuthFilter extends BasicAuthenticationFilter{

    String[] allIgnoreUrl;

    public JWTBasicAuthFilter(AuthenticationManager authenticationManager,String[] allIgnoreUrl) {
        super(authenticationManager);
        this.allIgnoreUrl = allIgnoreUrl;
    }

    /**
     * @description: 页面参数拦截解析
     * @author: wennn
     * @date: 5/9/20 5:31 PM
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        String header = request.getHeader(SecurityConst.AUTH_HEADER);

        log.debug("Request URL:  {}", request.getRequestURI());

        AntPathMatcher antPathMatcher = new AntPathMatcher();

        // 过滤不需要建权的请求
        for (String ul : this.allIgnoreUrl){
            if(antPathMatcher.match(ul,request.getRequestURI())){
                chain.doFilter(request,response);
                log.debug("patternPath:{},path:{},math:{}",ul,request.getRequestURI(),antPathMatcher.match(ul,request.getRequestURI()));
                return;
            }
        }

        // 这里没有权限访问 要提示登陆
        if (header == null || !header.startsWith(SecurityConst.AUTH_HEADER_PRE)) {
            throw new TokenException("非法请求，请登陆");
        }

        // 如果请求头中有token，则进行解析，并且设置认证信息
        JwtAuthToken authentication = JwtUtil.getAuthentication(request);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        System.out.println("完成token setAuthentication");
        super.doFilterInternal(request, response, chain);

    }


}

